/*****************************************************************************/
/*                                                                           */
/*    Domino Operation System Driver Module                                  */
/*                                                                           */
/*    Copyright (C) 2011 Laszlo Arvai                                        */
/*                                                                           */
/*    ------------------------------------------------------------------     */
/*    MCP3422/3/4 18-bit multi channel ADC driver                            */
/*****************************************************************************/

///////////////////////////////////////////////////////////////////////////////
// Include files
#include <drvI2C.h>
#include <drvMCP342x.h>
#include <drvIOConfig.h>

///////////////////////////////////////////////////////////////////////////////
// Constants
#define MCP342x_GENERATE_FUNCTION_NAME_PREFIX(x,y,z) x ## y ## z
#define MCP342x_I2C_Start(x,y,z)		MCP342x_GENERATE_FUNCTION_NAME_PREFIX(drv, x, Start)((y),(z))
#define MCP342x_I2C_WriteByte(x,y)	MCP342x_GENERATE_FUNCTION_NAME_PREFIX(drv, x, WriteByte)(y)
#define MCP342x_I2C_Restart(x,y,z)	MCP342x_GENERATE_FUNCTION_NAME_PREFIX(drv, x, Restart)((y),(z))
#define MCP342x_I2C_ReadByte(x,y) 	MCP342x_GENERATE_FUNCTION_NAME_PREFIX(drv, x, ReadByte)(y)
#define MCP342x_I2C_Stop(x)					MCP342x_GENERATE_FUNCTION_NAME_PREFIX(drv, x, Stop)()

///////////////////////////////////////////////////////////////////////////////
//! Initializes MCP324x device
void drvMCP342xInit(void)
{
	InitMCP342xI2C();
}

///////////////////////////////////////////////////////////////////////////////
//! Sets MCP324x device configration byte
//! \param Lower three bits of device I2C address
//! \param Configuration byte value
//! \return dosTrue if configuration byte is successfully updated
dosBool drvMCP342xSetConfiguration(dosByte in_address, dosByte in_configuration_byte)
{
	dosBool ack = MCP342x_I2C_Start(MCP342x_I2C, drvI2C_WRITE, drvMCP342x_BASE_ADDRESS + in_address);

	if( ack )
		MCP342x_I2C_WriteByte(MCP342x_I2C, in_configuration_byte);

	MCP342x_I2C_Stop(MCP342x_I2C);
    
	return ack;
}

///////////////////////////////////////////////////////////////////////////////
//! Gets A/D value from MCP324x device (max. 16 bit)
//! \param Lower three bits of device I2C address
//! \param Address of the variable receiving A/D value
//! \return dosTrue Data is valid
dosBool drvMCP342xGetWordData(dosByte in_address, dosWord* out_value)
{
	dosBool ack = dosFalse;
	dosBool success = dosFalse;
	dosByte config;
	
	*out_value = 0;
    
	// Set device in read mode
	ack = MCP342x_I2C_Start(MCP342x_I2C, drvI2C_READ, drvMCP342x_BASE_ADDRESS + in_address);

	if( ack )
	{    
		// read upper
		*out_value  = MCP342x_I2C_ReadByte(MCP342x_I2C, drvI2C_ACK) << 8;
	
  	// read lower
  	*out_value += MCP342x_I2C_ReadByte(MCP342x_I2C, drvI2C_ACK);
    
  	// read config bits
  	config = MCP342x_I2C_ReadByte(MCP342x_I2C, drvI2C_NACK);
	}
 
	// I2C stop 	
	MCP342x_I2C_Stop(MCP342x_I2C);
 
	// mask unused bits
	switch(config & drvMCP342x_RES_MASK)
	{
		case drvMCP342x_12_BIT:
    	*out_value  &= 0x0FFF;
			break;
      
		case drvMCP342x_14_BIT:
    	*out_value  &= 0x3FFF;
			break;

		case drvMCP342x_16_BIT:
      break;
	} 
    
  // result is valid only if !RDY is not set.
  return !(config & drvMCP342x_BUSY);
}
/*

BOOL drvMCP342xGetLongData(unsigned long * value)
{
    BOOL ack = FALSE;
    BYTE config = 0;
 
    if (!initialized) return FALSE;
 
    *value = 0;
    
    // Set device in read mode
    ack  = MCP3424ReadWrite(TRUE);
    
    switch(sampleRate)
    {
        case MCP3424_RATE_240:
            *value  = ((ReadI2C()&0x0F)<<8);
            break;
        case MCP3424_RATE_60:
            *value  = ((ReadI2C()&0x30)<<8);
            break;
         case MCP3424_RATE_15:
            *value  = ((ReadI2C()&0xFF)<<8);
            break;
        case MCP3424_RATE_3p75:
            *value  = ((ReadI2C()&0x03)<<16);
            *value += ((ReadI2C()&0xFF)<<8);
            break;
    }
    
    // Read lower
    *value += (ReadI2C()&0xFF);
    
    // Read config bits
    config = ReadI2C();
    
    // result is valid only if !RDY is not set.
    return (!(config>>7));
    
}
*/
